#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量运行所有测试用例脚本

功能：
- 扫描测试目录中的所有 .src 文件
- 为每个测试用例执行编译命令
- 收集并显示测试结果
- 支持通过命令行参数扩展功能
"""

import os
import sys
import subprocess
import argparse
from datetime import datetime


def get_test_files(test_dir):
    """
    获取测试目录中所有的 .src 文件
    
    Args:
        test_dir: 测试文件目录路径
    
    Returns:
        list: 测试文件路径列表
    """
    test_files = []
    for root, _, files in os.walk(test_dir):
        for file in files:
            if file.endswith('.src'):
                test_files.append(os.path.join(root, file))
    return test_files


def run_test(test_file, main_script):
    """
    运行单个测试用例
    
    Args:
        test_file: 测试文件路径
        main_script: 主程序脚本路径
    
    Returns:
        tuple: (是否成功, 输出信息, 错误信息)
    """
    try:
        # 构建命令
        cmd = [sys.executable, main_script, test_file]
        
        # 执行命令
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            check=False
        )
        
        # 判断是否成功（退出码为0表示成功）
        success = result.returncode == 0
        
        return success, result.stdout, result.stderr
    except Exception as e:
        return False, "", str(e)


def main():
    """
    主函数
    """
    # 解析命令行参数
    parser = argparse.ArgumentParser(description='批量运行dashun_script测试用例')
    parser.add_argument('--test-dir', 
                        default=os.path.join(os.path.dirname(__file__), 'test'),
                        help='测试文件目录路径')
    parser.add_argument('--main-script', 
                        default=os.path.join(os.path.dirname(__file__), 'main.py'),
                        help='主程序脚本路径')
    parser.add_argument('--filter', 
                        help='过滤测试文件名的关键字')
    parser.add_argument('--verbose', 
                        action='store_true',
                        help='显示详细输出信息')
    args = parser.parse_args()
    
    # 检查目录和文件是否存在
    if not os.path.isdir(args.test_dir):
        print(f"错误: 测试目录 '{args.test_dir}' 不存在")
        sys.exit(1)
    
    if not os.path.isfile(args.main_script):
        print(f"错误: 主程序脚本 '{args.main_script}' 不存在")
        sys.exit(1)
    
    # 获取测试文件
    test_files = get_test_files(args.test_dir)
    
    # 应用过滤
    if args.filter:
        test_files = [f for f in test_files if args.filter in os.path.basename(f)]
    
    if not test_files:
        print(f"错误: 在 '{args.test_dir}' 中未找到匹配的测试文件")
        sys.exit(1)
    
    # 显示测试信息
    print(f"===== 测试开始时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} =====")
    print(f"找到 {len(test_files)} 个测试用例")
    print(f"测试目录: {args.test_dir}")
    print()
    
    # 运行测试并收集结果
    results = []
    for i, test_file in enumerate(test_files, 1):
        test_name = os.path.basename(test_file)
        print(f"[{i}/{len(test_files)}] 运行测试: {test_name}")
        
        success, stdout, stderr = run_test(test_file, args.main_script)
        
        # 保存结果
        results.append({
            'file': test_name,
            'success': success,
            'stdout': stdout,
            'stderr': stderr
        })
        
        # 显示结果
        status = "通过" if success else "失败"
        print(f"  状态: {status}")
        
        # 显示详细信息（如果需要）
        if args.verbose:
            if stdout:
                print(f"  标准输出: {stdout[:100]}..." if len(stdout) > 100 else f"  标准输出: {stdout}")
            if stderr:
                print(f"  错误输出: {stderr[:100]}..." if len(stderr) > 100 else f"  错误输出: {stderr}")
        elif not success and stderr:
            # 失败时显示部分错误信息
            print(f"  错误信息: {stderr[:200]}..." if len(stderr) > 200 else f"  错误信息: {stderr}")
        
        print()
    
    # 汇总结果
    passed = sum(1 for r in results if r['success'])
    failed = len(results) - passed
    
    print("===== 测试结果汇总 =====")
    print(f"总测试数: {len(results)}")
    print(f"通过: {passed} ({passed/len(results)*100:.1f}%)")
    print(f"失败: {failed} ({failed/len(results)*100:.1f}%)")
    
    if failed > 0:
        print("\n失败的测试用例:")
        for result in results:
            if not result['success']:
                print(f"  - {result['file']}")
    
    print(f"\n测试结束时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    
    # 根据测试结果设置退出码
    sys.exit(0 if failed == 0 else 1)


if __name__ == '__main__':
    main()